dungeonHandler = dungeonHandler or {};
G.serverData = G.serverData or {};
require "proto/dungeon/message/ReqDungeonStarMessage"
require "proto/dungeon/message/ReqFormationMessage"
require "proto/task/message/ReqServerTaskRewardMessage"
require "proto/task/message/ReqServerTaskMessage"
require "proto/dungeon/message/ReqDungeonStarInfoMessage"
require "proto/dungeon/message/ReqDungeonRankMessage"
require "proto/dungeon/message/ReqDungeonPassHistoriesMessage"
require "proto/dungeon/message/ReqSkipDungeonMessage"
require "proto/dungeon/message/ReqQuitGroupBossMessage"
require "proto/dungeon/bean/GroupFormationPortoBean"
require "proto/dungeon/message/ReqDungeonRankListMessage"
require "proto/dungeon/message/ReqBossMessage"
require "proto/battle/message/ReqBattleReportPathMessage"
require "proto/dungeon/message/ReqHardDungeonInfoMessage"
require "proto/dungeon/message/ReqHardGroupBossMessage"
require "proto/dungeon/message/ResHardDungeonRushMessage"
require "proto/dungeon/message/ReqQuitHardGroupBossMessage"
require "proto/dungeon/message/ReqHardDungeonRankListMessage"

--- @param msg ResBossMessage 挑战boss返回
dungeonHandler.battleInfo = nil;
dungeonHandler.sendBoss = false
dungeonHandler.sendBossTime = 0
dungeonHandler.hardData = {}
function dungeonHandler.receiveBoss(msg)
    --log("dungeonHandler.receiveBoss");
    --dataTable.PrintTable(msg);
    if msg.state == 0 then
        BattlePlaybackManager.GotoFight(EnumConst.FightTypeConst.DUNGEON)
        TAManager.TrackByDictionary("join_dungeon_battle")
        --[[local idStr = tostring(msg.dungeonId);
        -- TDGABehavior.MissionBegin(idStr);
        LoginSDK.GetInstance():MissionBegin(idStr);

        -- 处理战斗结果
        if msg.fightResult > 0 then
            -- logicMgr.FlashGiftManager.checkIsNeedAddNewFlashGift(EnumConst.FlashGiftType.MAIN, idStr);
            logicMgr.CostManager.setPlayerBehaviorTime(Config.CostOpenCondition.AchieveCustom, idStr);
            -- TDGABehavior.MissionComplect(idStr);
            LoginSDK.GetInstance():MissionComplect(idStr);

            local newMapId = logicMgr.MapManager.getNextStage();
            if newMapId~=nil and newMapId>0 then
                logicMgr.MapManager.setMapId(newMapId);
            end
        else
            -- TDGABehavior.MissionFail(idStr,"");
            LoginSDK.GetInstance():MissionFail(idStr,"");
        end

        -- 战利品设置
        FightManager.resultItems = {};
        for i =1,#msg.items do
            local itemModelId = msg.items[i].itemModelId;
            local type = Mathf.Floor(itemModelId/100000);
            local itemData;
            if type == EnumConst.ItemTableEnum.Equip then
                itemData = logicMgr.EquipManager.getEquipConstDatabyModelId(itemModelId);
            else
                itemData = logicMgr.ItemManager.getItemConstDatabyModelId(itemModelId);
            end
            if itemData then
                itemData["itemModelId"] = msg.items[i].itemModelId;
                itemData["num"] = msg.items[i].num;
                table.insert(FightManager.resultItems,itemData)
            else
                logError("[receiveBoss]can't find item or equip config by id:"..itemModelId)
            end
        end
        --FireEvent(Config.EventType.Fight_Enter);
        BattlePlaybackManager.setBattleRecord(msg.record)
        BattlePlaybackManager.setBattleResult(msg.fightResult)
        -- 请求战斗命令，然后回放战斗
        BattlePlaybackManager.requestFightCmdThenPlay(msg.record, EnumConst.FightTypeConst.DUNGEON)]]

        --BattlePlaybackManager.RequestReport(msg.fightId,msg.fightResult,EnumConst.FightTypeConst.DUNGEON,msg.record)
        --else
        --UISysTips.AddMsg("进入战斗错误-");
        -- printError("进入战斗错误-",msg.state);
        --UIBattle.replyBattle();
    end
end

function dungeonHandler.receiveDungeon(msg)
    --log("dungeonHandler.receiveDungeon");
    --dataTable.PrintTable(msg);
    if msg.state == 0 then
        logicMgr.FubenModel.SetPassTimeForLast(msg.lastPassTime)
        logicMgr.MapManager.setMapId(msg.dungeonId);
        logicMgr.HeroManager.setSettleTime(msg.settleTime == nil and 0 or msg.settleTime);
        logicMgr.HeroManager.setQuickTimes(msg.quickTimes == nil and 0 or msg.quickTimes);
        logicMgr.DungeonRandomEventManager.setDungeonRandomEventData(msg.dungeonRandomEventTimes, msg.dungeonRandomEvent);
        logicMgr.DungeonRandomEventManager.setDungeonRandomEventHeroData(msg.helpPartner);
    end
end

function dungeonHandler.receiveFormation(msg)
    --log("dungeonHandler.receiveFormation");
    --dataTable.PrintTable(msg);
    if msg.state == 0 then
        logicMgr.FormationManager.SetFormation(EnumConst.FormationType.Duplicate, msg.formation,msg.correctLv);
        if msg.groupFormation then
            local data = {};
            for k, v in pairs(msg.groupFormation) do
                data[v.groupId] = v.formation;
            end
            logicMgr.FormationManager.SetFormation(EnumConst.FormationType.DuplicateMore, data);
        end
        FireEvent(Config.EventType.Fresh_BattleFormation);
    end
end

function dungeonHandler.pushGroupBossHistory(msg)
    if msg.state == 0 then
        for k, v in pairs(msg.histories) do
            logicMgr.BattlePlaybackManager.UpdateGroupBossHistory(v);
        end
    end
end

function dungeonHandler.receiveDungeonStar(msg)
    if msg.state == 0 then
        FireEvent(Config.EventType.FreashDungeonAGree, msg.star);
    end
end

function dungeonHandler.receiveDungeonStarInfo(msg)
    if msg.state == 0 then
        FireEvent(Config.EventType.FreashDungeonAGreeAlready, msg.isStar);
    end
end

function dungeonHandler.receiveDungeonTask(msg)
    if msg.state == 0 then
        logicMgr.MapManager.DungeonTaskTable = {}
        for i = 1, #msg.tasks do
            local singleTask = msg.tasks[i];
            logicMgr.MapManager.DungeonTaskTable[tostring(singleTask.taskId)] = singleTask;
        end
        FireEvent(Config.EventType.FreashDungeonTask, msg);
    end
end

function dungeonHandler.receiveDungeonTaskAward(msg)
    if msg.state == 0 then
        FireEvent(Config.EventType.FreashDungeonTaskAward, msg);
    end
end

function dungeonHandler.receiveDungeonRank(msg)
    if msg.state == 0 then
        FireEvent(Config.EventType.FreashDungeonStar, msg);
    end
end

function dungeonHandler.ReqDungeonRankList()
    local req = ReqDungeonRankListMessage.New()
    sendReqMessage(req)
end

function dungeonHandler.ResDungeonRankList(msg)
    if msg.state == 0 then
        FireEvent(Config.EventType.FreashDungeonList,msg)
    end
end

function dungeonHandler.reqQuitGroupBoss()
    local msg = ReqQuitGroupBossMessage.New();
    sendReqMessage(msg);
end

function dungeonHandler.sendBossMessage(dungeonId, formation, battleInfo)
    --log("============dungeonHandler.sendBossMessage"..dungeonId)
    --不能完全杜绝弱网时重复发包。能减少一部分，并防止丢包阻断出现。
    --彻底解决还是要通过任务判断
    if os.time() - dungeonHandler.sendBossTime < 3 then
        return
    end
    dungeonHandler.battleInfo = battleInfo;
    local msg = ReqBossMessage.New();
    msg.dungeonId = dungeonId;
    msg.version = Config.ProtoVersion;
    msg.formation = formation;
    msg.serialId = 0

    dungeonHandler.sendBossTime = os.time()
    sendReqMessage(msg);
end

function dungeonHandler.sendGroupBossMessage(dungeonId, formation, battleInfo, index)
    dungeonHandler.battleInfo = battleInfo;
    local msg = ReqGroupBossMessage.New();
    msg.dungeonId = dungeonId;
    msg.bossGroupId = index;
    msg.formations = {};
    for i = 1, logicMgr.MapManager.getStageNeedTeamNum() do
        local _data = GroupFormationPortoBean.New();
        _data.groupId = i;
        _data.formation = formation[i];
        table.insert(msg.formations, _data);
    end
    sendReqMessage(msg);
end

function dungeonHandler.sendFormation()
    local msg = ReqFormationMessage.New();
    sendReqMessage(msg);
end

function dungeonHandler.sendReqDungeonStar()
    local msg = ReqDungeonStarMessage.New();
    sendReqMessage(msg);
end

function dungeonHandler.sendReqDungeonStarInfo()
    local msg = ReqDungeonStarInfoMessage.New();
    sendReqMessage(msg);
end

function dungeonHandler.sendDungeonTask()
    local msg = ReqServerTaskMessage.New();
    sendReqMessage(msg);
end

function dungeonHandler.sendDungeonTaskAward(sendTask)
    local msg = ReqServerTaskRewardMessage.New();
    msg.taskId = sendTask;
    sendReqMessage(msg);
end
function dungeonHandler.ReqBattleReportPathMessage(fightId,reportPath)
    local msg = ReqBattleReportPathMessage.New()
    msg.fightId = fightId
    msg.fightReportPath = reportPath
    sendReqMessage(msg)
end
function dungeonHandler.sendreqSpeedRace()
    local msg = ReqDungeonRankMessage.New();
    sendReqMessage(msg);
end

function dungeonHandler.sendReqDungeonPassHistories(dungeonId,type)
    local msg = ReqDungeonPassHistoriesMessage.New();
    msg.dungeonId = dungeonId;
    msg.type = type;
    sendReqMessage(msg);
end

function dungeonHandler.sendReqSkipDungeon()
    local msg = ReqSkipDungeonMessage.New();
    sendReqMessage(msg);
end

---服务器主动通知客户端战斗完成
function dungeonHandler.ResDungeonBossFinishBattleHandler(msg)
    UIWaiting.WaitingHide()
    if msg.state ~= 0 then
        logError("进入战斗错误-战斗返回失败 code:" .. msg.state)
        FireEvent(Config.EventType.LoadingCancelByFightError, "战斗返回失败")
        return
    end
    if FightManager.timerId then
        utimer.remove(FightManager.timerId)
        FightManager.timerId = nil
    end
    logicMgr.MapManager.SetetAutoMapId(msg.dungeonId)
    logicMgr.BattlePlaybackManager.SetGroupBossNowGroupId(msg.groupId);
    local type = logicMgr.BattlePlaybackManager.GetFightType()
    if type == EnumConst.FightTypeConst.DUNGEON then
        local idStr = tostring(msg.dungeonId);
        -- TDGABehavior.MissionBegin(idStr);
        LoginSDK.GetInstance():MissionBegin(idStr);
        if msg.fightResult > 0 then
            local _, flag = logicMgr.BattlePlaybackManager.GetGroupBossJoinGroupId();
            if flag or logicMgr.MapManager.getStageNeedTeamNum() <= 1 then
                logicMgr.BattlePlaybackManager.SetGroupBossIsOver(true);
                logicMgr.MapManager.SetIsCanSkip(msg.skipFlag == 1);
                logicMgr.CostManager.setPlayerBehaviorTime(Config.CostOpenCondition.AchieveCustom, idStr);
                -- TDGABehavior.MissionComplect(idStr);
                LoginSDK.GetInstance():MissionComplect(idStr);
                logicMgr.MapManager.setMapId(msg.dungeonId);
                FireEvent(Config.EventType.Fresh_NewStage);--刷新各个功能解锁
                playerHandler.CheckSendFuncUnlock()
                logicMgr.ActiveManager.updateActiveLimit();
                if FuncOpenManager.isOpen(Config.FuncOpenType.SupSkill) and table.getn(logicMgr.SkillManager.getSupSkillInfo()) <= 0 then
                    skillHandler.SendReqAssistantSkill();
                end
                logicMgr.UnlockFuncManager.updateUnlockFunc(); -- 解锁功能，发起协议

                -- iOS Widget: 更新主线关卡进度
                if CompareOriginVersion("1.4.2.0001") then
                    LoginSDK.GetInstance():SetWidgetUserStage(msg.dungeonId)
                end
            end
        else
            -- TDGABehavior.MissionFail(idStr,"");
            LoginSDK.GetInstance():MissionFail(idStr, "");
        end
        logicMgr.DungeonRandomEventManager.setDungeonRandomEventData(nil, msg.dungeonRandomEvent);
        dungeonHandler.TADungeonRandomEvent(msg.dungeonRandomEvent);
    end

    FightManager.InitRewards(msg.items)
    log("dungeon fightId:" .. tostring(msg.fightId) .. ",result:" .. tostring(msg.fightResult))
    local mapCfg = MapManager.GetMapcfgByID(MapManager.getLastMapcfg())
    if string.IsNilOrEmpty(mapCfg.f_ReportAddress) then
        logicMgr.BattlePlaybackManager.RequestReport(msg.fightId, msg.fightResult, msg.record)
    end
end

function dungeonHandler.TADungeonRandomEvent(dungeonRandomEvent)
    if dungeonRandomEvent ~= nil and dungeonRandomEvent.type ~= nil then
        local randomEvent = {}
        randomEvent.eventType = dungeonRandomEvent.type;
        TAManager.TrackByDictionary("dungeonRandomEvent",randomEvent);
    end
end

---主线跳关成功
function dungeonHandler.ResSkipSuccHandler(msg)
    if msg.state == 0 then
        local idStr = tostring(msg.dungeonId);
        LoginSDK.GetInstance():MissionBegin(idStr);
        logicMgr.CostManager.setPlayerBehaviorTime(Config.CostOpenCondition.AchieveCustom, idStr);
        LoginSDK.GetInstance():MissionComplect(idStr);
        logicMgr.MapManager.setMapId(msg.dungeonId);
        logicMgr.MapManager.SetBattleBeforeMapId(logicMgr.MapManager.getMapId())
        FireEvent(Config.EventType.Fresh_NewStage);--刷新各个功能解锁
        playerHandler.CheckSendFuncUnlock()
        logicMgr.ActiveManager.updateActiveLimit();
        FightManager.InitRewards(msg.items)
        UIBattle.RefreshChapterRewardBtn();
        -- iOS Widget: 更新主线关卡进度
        if CompareOriginVersion("1.4.2.0001") then
            LoginSDK.GetInstance():SetWidgetUserStage(msg.dungeonId)
        end
        if FightManager.isAuto then
            FightManager.AutoGoFight()
        else
            showUI(PanelNames.UICommonItemGet, nil, nil, 3, FightManager.resultItems);
        end
        FightManager.autoJump = nil
    end
end

function dungeonHandler.ResBattleHandler(msg)
    dungeonHandler.sendBossTime = 0

    if msg.state ~= 0 then--[[屏蔽前端战斗or msg.battleType == EnumConst.FightTypeConst.SoloChaosTest then]]
        return
    end
    local type = msg.battleType
    if type == nil then
        logError("[ResBattle]battleType is nil,服务器要传enum type")
        return
    end
    if type == EnumConst.FightTypeConst.DUNGEON then
        TAManager.TrackByDictionary("dungeon_join_battle")
    elseif type == EnumConst.FightTypeConst.ARENARECORD then
        type = EnumConst.FightTypeConst.ARENA
    elseif type == EnumConst.FightTypeConst.TOWER then
        TAManager.TrackByDictionary("tower_join_battle")
    end
    logicMgr.BattlePlaybackManager.ResetReceiveReport()
    local mapCfg = MapManager.getMapcfg();
    local flag = type ~= EnumConst.FightTypeConst.DUNGEON or string.IsNilOrEmpty(mapCfg.f_ReportAddress)
    if  flag and not ArenaManager.getSomeBattleSkip() then
        logicMgr.BattlePlaybackManager.GotoFight(type)
    end

end

function dungeonHandler.ResDungeonPassHistories(msg)
    local playerDataList = {};
    if tonumber(msg.state) == 0 and msg.histories ~= nil then
        local towerRecord = msg.histories;
        for i = 1, #towerRecord do
            local playerData = {};
            --playerData["rawRecord"] = towerRecord[i].group[1].record;
            --playerData["playerId"] = tonumber(tostring(towerRecord[i].playerId));
            playerData["playerName"] = towerRecord[i].name;
            playerData["icon"] = towerRecord[i].pic;
            playerData["headFrame"] = towerRecord[i].picFrame;
            playerData["time"] = tonumber(tostring(towerRecord[i].group[#towerRecord[i].group].passTime));
            playerData["power"] = tonumber(tostring(towerRecord[i].power));
            playerData["group"] = towerRecord[i].group;

            playerData["heroList"] = {};
            local fomation = towerRecord[i].group[1].record.attacker.members;
            for i = 1, #fomation do
                if tonumber(fomation[i].partnerModelId) > 0 then
                    local partnerModelId = tostring(fomation[i].partnerModelId);
                    local partnerInfo = {};
                    partnerInfo["partnerId"] = fomation[i].partnerModelId;
                    partnerInfo["partnerModelId"] = partnerModelId
                    partnerInfo["level"] = fomation[i].level;
                    partnerInfo["star"] = fomation[i].star;
                    partnerInfo["quality"] = logicMgr.HeroManager.starToQuality(fomation[i].star)
                    table.insert(playerData["heroList"], partnerInfo);
                end
            end
            table.insert(playerDataList, playerData)
        end
    end
    FireEvent(Config.EventType.Fresh_DungeonRecord, {
        playerDataList = playerDataList
    })
end

function dungeonHandler.ReqHardDungeonInfoHandler()--请求多队数据
    local req= ReqHardDungeonInfoMessage.New()
    sendReqMessage(req)
end

function dungeonHandler.ResHardDungeonInfoHandler(msg)
    if msg.state == 0 then
        dungeonHandler.hardData = msg.data
        logicMgr.StoryHardManager.setServerData(msg.data);
        local data = {};
        for k, v in pairs(msg.data.groupFormation) do
            data[v.groupId] = v.formation;
        end
        logicMgr.FormationManager.SetFormation(EnumConst.FormationType.StoryDuplicate, data);
        FireEvent(Config.EventType.HardStoryInfo)
    end
end



function dungeonHandler.ReqHardGroupBossoHandler(dungeonId,bossGroupId,formations)--请求多队战斗
    local req= ReqHardGroupBossMessage.New()
    req.dungeonId=dungeonId
    req.bossGroupId=bossGroupId
    local team = {}
    for k,v in pairs(formations) do
        local g = GroupFormationPortoBean.New()
        g.groupId = k
        g.formation = v
        team[k] = g
    end
    req.formations= team
    sendReqMessage(req)
    logicMgr.StoryHardManager.MarkRecord()
    --printError("发送了请求多队战斗消息")
end


function dungeonHandler.ReqHardDungeonRush(dungeonId,times)-- 请求多队扫荡
    local req= ReqHardDungeonRushMessage.New()
    req.dungeonId=dungeonId
    req.times=times
    sendReqMessage(req)
    --printError("发送了请求扫荡消息")
end

function dungeonHandler.ResHardDungeonRushHandler(msg)
    if msg.state == 0 then
        dungeonHandler.ReqHardDungeonInfoHandler()
        logicMgr.StoryHardManager.updateDungeonPassTimes(msg.dungeonId, msg.times)
        FireEvent(Config.EventType.HardStoryTimes, msg.data)

        StoryHardManager.UploadRecord(msg.dungeonId, msg.times)
    end
end

function dungeonHandler.ResHardDungeonBossFinishBattleHandler(msg)--服务器主动推送战斗完成的消息
    if logicMgr.BattlePlaybackManager.GetGroupBossIsOver() then
        logicMgr.BattlePlaybackManager.SetGroupBossHistory();
    end
    UIWaiting.WaitingHide()
    if msg.state ~= 0 then
        logError("进入战斗错误-战斗返回失败 code:" .. msg.state)
        FireEvent(Config.EventType.LoadingCancelByFightError, "战斗返回失败")
        return
    end
    dump(msg, "幻魔之旅战斗返回", 10)
    --  logicMgr.BattlePlaybackManager.SetFightType(EnumConst.FightTypeConst.StoryBattle)
    --  printError("打的关卡",msg.dungeonId,msg.groupId,msg.formation,msg.record.win)
    logicMgr.BattlePlaybackManager.SetGroupBossNowGroupId(msg.groupId);
    logicMgr.BattlePlaybackManager.UpdateGroupBossHistory(msg)
    logicMgr.BattlePlaybackManager.RequestReport(msg.fightId, msg.fightResult, msg.record)
    logicMgr.StoryHardManager.setChapterReward(msg.items);
    logicMgr.MapManager.SetStoryHardAutoMapId(msg.dungeonId, msg.groupId);
    StoryHardManager.CacheRecord(msg.dungeonId, msg.groupId, msg.fightResult)
    logicMgr.MapManager.SetStoryHardAutoMapId(msg.dungeonId, msg.groupId);
    StoryHardManager.CacheRecord(msg.dungeonId, msg.groupId, msg.fightResult)
    local _, flag = logicMgr.BattlePlaybackManager.GetGroupBossJoinGroupId(EnumConst.FightTypeConst.StoryBattle);
    if flag then
        logicMgr.BattlePlaybackManager.SetGroupBossIsOver(true);
        dungeonHandler.ReqHardDungeonInfoHandler()
    end
    if logicMgr.ArenaManager.getSomeBattleSkip() then
        if logicMgr.BattlePlaybackManager.GetGroupBossIsOver() then
            logicMgr.StoryHardManager.setPower(logicMgr.StoryHardManager.getPower() - logicMgr.StoryHardManager.getBattlePower());
        end
        logicMgr.BattlePlaybackManager.SetFightType(EnumConst.FightTypeConst.StoryBattle)
        FightManager.showResultUI(true);
        closeUI(PanelNames.UIBattleTeam)
        logicMgr.StoryHardManager.setIsEntryBattle(false);
    end
    if isOpenUI(PanelResNames.UITeamsDetails2) then
        CtrlManager.GetCtrl(PanelNames.UITeamsDetails2):OnClose();
    end
end

function dungeonHandler.ReqQuitHardGroupBoss()-- 退出队伍
    local req = ReqQuitHardGroupBossMessage.New()
    sendReqMessage(req)
end

function dungeonHandler.ReqHardDungeonRankList()-- 请求幻魔之旅排行榜信息
    local req = ReqHardDungeonRankListMessage.New()
    sendReqMessage(req)
end

function dungeonHandler.ResHardDungeonRankList(msg)-- 请求幻魔之旅排行榜信息
    if msg.state == 0 then
        logicMgr.StoryHardManager.SetRanks(msg)
    end
end



